﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Model.cs" company="Jarno Burger">
//   Jarno Burger
// </copyright>
// <summary>
//   This contains all the measured values..
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace MyDomotica.Model
{
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Runtime.CompilerServices;

    using MyDomotica.Properties;

    /// <summary>
    /// This contains all the measured values..
    /// </summary>
    public sealed class Model : INotifyPropertyChanged
    {
        #region Declare
        /// <summary>
        /// The current temperature.
        /// </summary>
        private float currentTemperature;

        /// <summary>
        /// The current humidity.
        /// </summary>
        private float currentHumidity;

        /// <summary>
        /// The current brightness.
        /// </summary>
        private float currentBrightness;

        /// <summary>
        /// The current motion.
        /// </summary>
        private bool currentMotion;

        /// <summary>
        /// If the heater is currently on.
        /// </summary>
        private bool currentHeaterIsOn;

        /// <summary>
        /// The current message.
        /// </summary>
        private string currentMessage;

        /// <summary>
        /// The current in between time before a internet data-push.
        /// </summary>
        private float currentInternetPushProgress;

        /// <summary>
        /// The current preferred temperature.
        /// </summary>
        private float currentPreferredTemperature;

        /// <summary>
        /// Occurs when for a property its value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #region Initialize
        public Model()
        {
            this.CurrentPreferredTemperature = Constants.EndOfMiddayHour;
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the current temperature.
        /// </summary>
        /// <value>
        /// The current temperature.
        /// </value>
        public float CurrentTemperature
        {
            get
            {
                return this.currentTemperature;
            }

            set
            {
                if (value.Equals(this.currentTemperature))
                {
                    return;
                }

                this.currentTemperature = value;
                this.ValidateCurrentValues();
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the current humidity.
        /// </summary>
        /// <value>
        /// The current humidity.
        /// </value>
        public float CurrentHumidity
        {
            get
            {
                return this.currentHumidity;
            }

            set
            {
                if (value.Equals(this.currentHumidity))
                {
                    return;
                }

                this.currentHumidity = value;
                this.ValidateCurrentValues();
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the current brightness.
        /// </summary>
        /// <value>
        /// The current brightness.
        /// </value>
        public float CurrentBrightness
        {
            get
            {
                return this.currentBrightness;
            }

            set
            {
                if (value.Equals(this.currentBrightness))
                {
                    return;
                }

                this.currentBrightness = value;
                this.ValidateCurrentValues();
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether there is motion.
        /// </summary>
        /// <value>
        ///   <c>true</c> if [motion]; otherwise, <c>false</c>.
        /// </value>
        public bool CurrentMotion
        {
            get
            {
                return this.currentMotion;
            }

            set
            {
                if (value.Equals(this.currentMotion))
                {
                    return;
                }

                this.currentMotion = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the heater is currently on.
        /// </summary>
        /// <value>
        ///   <c>true</c> if [current heater is on]; otherwise, <c>false</c>.
        /// </value>
        public bool CurrentHeaterIsOn
        {
            get
            {
                return this.currentHeaterIsOn;
            }

            set
            {
                //if (value.Equals(this.currentHeaterIsOn))
                //{
                //    return;
                //}

                this.currentHeaterIsOn = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the current message.
        /// </summary>
        /// <value>
        /// The current message.
        /// </value>
        public string CurrentMessage
        {
            get
            {
                return this.currentMessage;
            }

            set
            {
                if (value.Equals(this.currentMessage))
                {
                    return;
                }

                this.currentMessage = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the current counter in between a new web push.
        /// </summary>
        /// <value>
        /// The current internet push progress.
        /// </value>
        public float CurrentInternetPushProgress
        {
            get
            {
                return this.currentInternetPushProgress;
            }

            set
            {
                this.currentInternetPushProgress = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the current preferred temperature.
        /// </summary>
        /// <value>
        /// The current preferred temperature.
        /// </value>
        public float CurrentPreferredTemperature
        {
            get
            {
                return this.currentPreferredTemperature;
            }

            set
            {
                this.currentPreferredTemperature = value;
                this.OnPropertyChanged();
            }
        }
        #endregion

        #region Notify
        /// <summary>
        /// Called when [property changed].
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        [NotifyPropertyChangedInvocator]
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = this.PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region Validate
        /// <summary>
        /// Makes sure that all current values fall in between their ranges..
        /// </summary>
        public void ValidateCurrentValues()
        {
            if (this.currentTemperature < Constants.PossibleTemperatureMin)
            {
                Debug.WriteLine("Fixing temperature");
                this.currentTemperature = Constants.PossibleTemperatureMin;
            }

            if (this.currentTemperature > Constants.PossibleTemperatureMax)
            {
                Debug.WriteLine("Fixing temperature");
                this.currentTemperature = Constants.PossibleTemperatureMax;
            }

            if (this.currentHumidity < Constants.PossibleHumidityMin)
            {
                Debug.WriteLine("Fixing humidity");
                this.currentHumidity = Constants.PossibleHumidityMin;
            }

            if (this.currentHumidity > Constants.PossibleHumidityMax)
            {
                Debug.WriteLine("Fixing humidity");
                this.currentHumidity = Constants.PossibleHumidityMax;
            }

            if (this.currentBrightness < Constants.PossibleBrightnessMin)
            {
                Debug.WriteLine("Fixing brightness");
                this.currentBrightness = Constants.PossibleBrightnessMin;
            }

            if (this.currentBrightness > Constants.PossibleBrightnessMax)
            {
                Debug.WriteLine("Fixing brightness");
                this.currentBrightness = Constants.PossibleBrightnessMax;
            }
        }
        #endregion
    }
}
